package net.hiapoe.gsnake4j.listener;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.text.SimpleDateFormat;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import net.hiapoe.gsnake4j.bean.Drawer;
import net.hiapoe.gsnake4j.bean.Snake;
import net.hiapoe.gsnake4j.bean.Snake.Direction;
import net.hiapoe.gsnake4j.window.RunMe;
/**
 * 
 * @Author Administrator
 * @Description 单实例, 监听窗口
 * @Version 1.0.3
 * @Date 2013年10月1日
 */
public class MainWinListener implements ActionListener, KeyListener {
	
	public final static String TAG="ByUser";
	private JFrame jframe = null;
	private static MainWinListener listerner = null;
	private static long last_moved_time_by_interval = Snake.getLastmoved(); //最后一次周期响应的时间
	private static long last_moved_times_by_key=0; //最后一次由键盘响应的次数
	private static boolean is_key_sensitive=false;//键盘敏感会在转弯时立即响应一次，不敏感则会根据在每个时间周期响应一次。（两者均含包括按键、移动和重绘）
	@SuppressWarnings("unused")
	private static boolean is_typed_back=false;
	private MainWinListener(JFrame jframe) {
		this.jframe = jframe;
	}

	public static synchronized MainWinListener getInstance(JFrame jframe) {
		if (MainWinListener.listerner == null) {
			MainWinListener.listerner = new MainWinListener(jframe);
		}
		return MainWinListener.listerner;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		String command = e.getActionCommand();
		if (command.equals("重新开始")) {
			Snake.reLive();
		} else if (command.equals("退出")) {
			System.exit(0);
		}else if(command.equals("实时响应")){
			is_key_sensitive=true;
			JOptionPane.showMessageDialog(jframe, "按键已更改为实时响应", "消息", JOptionPane.INFORMATION_MESSAGE);
		}else if(command.equals("周期响应")){
			is_key_sensitive=false;
			JOptionPane.showMessageDialog(jframe, "按键已更改为周期响应", "消息", JOptionPane.INFORMATION_MESSAGE);
		}else if (command.equals("最高得分")) {
			String formatedtime = new SimpleDateFormat("mm分:ss秒").format(Snake
					.getInstance().getRecord_runtime());
			JOptionPane.showMessageDialog(jframe, "局数: 第"
					+ Snake.getInstance().getRecord_times() + "局\r\n得分: "
					+ Snake.getInstance().getRecord_point() + "\r\n所用时间: "
					+ formatedtime, "最高得分", JOptionPane.INFORMATION_MESSAGE);
		} else if (command.equals("操作方法")) {
			JOptionPane
					.showMessageDialog(
							jframe,
							"方向键: 控制方向和速度\r\n空格键: 开始/暂停\r\nShift键: 恢复默认速度\r\nEsc键 : 退出\r\n注意: ☆周期响应模式下按键过快可导致操作失灵☆",
							"操作指南", JOptionPane.INFORMATION_MESSAGE);
		} else if (command.equals("关于")) {
			JOptionPane.showMessageDialog(this.jframe,
					"作者: "+RunMe.AUTHOR+"\r\n邮箱: "+RunMe.EMAIL+"\r\n版本: " + RunMe.VERSION,
					" 关于 ", JOptionPane.INFORMATION_MESSAGE);
		}

	}

	@Override
	public synchronized void keyPressed(KeyEvent e) {
		int keycode = e.getKeyCode();
		if (keycode == KeyEvent.VK_SPACE) {
			Snake.getInstance().setIsrunable(
					!Snake.getInstance().getIsrunable());
		} else if (keycode == KeyEvent.VK_ESCAPE) {
			boolean isrunable = Snake.getInstance().getIsrunable();
			Snake.getInstance().setIsrunable(false);
			if (JOptionPane.showConfirmDialog(jframe, "确认退出?", "你确定?",
					JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
				System.exit(0);
			}
			Snake.getInstance().setIsrunable(isrunable);
		}
		// 暂停时禁用其他按键
		if (!Snake.getInstance().getIsrunable()) {
			return;
		}
		// 在非键盘敏感的情况下，若未到达响应周期则不作处理
		if (!is_key_sensitive&&System.currentTimeMillis() - last_moved_time_by_interval < Snake
				.getInstance().getInterval()) {
			return;
		}
		Direction loggedsnakedirection = Snake.getInstance().getDirection();
		if (keycode == KeyEvent.VK_UP) {
			Snake.getInstance().setDirection(Direction.UP);
		} else if (keycode == KeyEvent.VK_DOWN) {
			Snake.getInstance().setDirection(Direction.DOWN);
		} else if (keycode == KeyEvent.VK_LEFT) {
			Snake.getInstance().setDirection(Direction.LEFT);
		} else if (keycode == KeyEvent.VK_RIGHT) {
			Snake.getInstance().setDirection(Direction.RIGHT);
		} else if (keycode == KeyEvent.VK_SHIFT) {
			Snake.getInstance().setInterval(Snake.DEFAUTL_INTERVAL);
		} else {
			return;
		}
		if (loggedsnakedirection.value == Snake.getInstance().getDirection().value) {
			Snake.getInstance().speedUp();
		} else if (loggedsnakedirection.value == -Snake.getInstance()
				.getDirection().value) {
			Snake.getInstance().speedDown();
			Snake.getInstance().setDirection(loggedsnakedirection);
			if(is_key_sensitive){
				is_typed_back=true;
			}
		}
		// 周期响应则记录上次周期响应时间以在监听器中控制按键
		// 实时响应则记录最后一次由键盘响应次数，若在一个Snake周期内有新的键盘响应则暂停一个周期后运动
		if(!is_key_sensitive){
			last_moved_time_by_interval = Snake.getLastmoved();
		}else{
			// 只响应相对于左右的按键
			if(Math.abs(Math.abs(loggedsnakedirection.value)-Math.abs(Snake.getInstance()
					.getDirection().value))==1){
				last_moved_times_by_key++;
				Snake.move(TAG);
				Drawer.reFresh();
			}
			// 只响应非后退键
			/*if(!is_typed_back){
				last_moved_times_by_key++;
				Snake.move(TAG);
				Drawer.reFresh();
			}
			is_typed_back=false;*/
		}

	}

	@Override
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	public static boolean isIs_key_sensitive() {
		return is_key_sensitive;
	}

	public static long getLast_moved_times_by_key() {
		return last_moved_times_by_key;
	}

}
